package com.example.myspringframework.context.annotation;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.TypeUtil;
import com.example.myspringframework.beans.factory.BeanFactory;
import com.example.myspringframework.beans.BeansException;
import com.example.myspringframework.beans.factory.BeanFactoryAware;
import com.example.myspringframework.beans.factory.ConfigurableListableBeanFactory;
import com.example.myspringframework.beans.PropertyValues;
import com.example.myspringframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import com.example.myspringframework.core.convert.ConversionService;

import java.lang.reflect.Field;

/**
 * 在属性赋值前解析@Value和@Autowired注解
 */
public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {
    private ConfigurableListableBeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        // 处理Value注解
        Class<?> beanClass = bean.getClass();
        Field[] fields = beanClass.getDeclaredFields();
        for (Field field : fields) {
            Value annotation = field.getAnnotation(Value.class);
            if (annotation != null) {
                Object value = annotation.value();
                // 把占位符${]替换成真正的值
                value = beanFactory.resolveEmbeddedValue((String) value);

                // value类型转换
                Class<?> sourceClass = value.getClass();
//                Class<?> targetClass = (Class<?>) TypeUtil.getType(field);
                Class<?> targetClass = (Class<?>) field.getGenericType();
                ConversionService conversionService = this.beanFactory.getConversionService();
                if (conversionService != null) {
                    if (conversionService.canConvert(sourceClass, targetClass)) {
                        value = conversionService.convert(value, targetClass);
                    }
                }
                // 给属性赋值
                try {
                    field.setAccessible(true);
                    field.set(bean,value);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
//                BeanUtil.setFieldValue(bean,field.getName(),value);
            }
        }
        // 处理Autowired注解
        for (Field field : fields) {
            Autowired autowired = field.getAnnotation(Autowired.class);
            if (autowired != null) {
                Qualifier qualifier = field.getAnnotation(Qualifier.class);
                Object dependentBean = null;
                //Qualifier注解存在则根据beanName获取，否则根据类型获取bean
                if (qualifier != null) {
                    String dependentBeanName  = qualifier.value();
                    dependentBean = beanFactory.getBean(dependentBeanName);
                }else {
                    dependentBean = this.beanFactory.getBean(field.getType());
                }
                try {
                    field.setAccessible(true);
                    field.set(bean,dependentBean);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
//                BeanUtil.setFieldValue(bean,field.getName(),dependentBean);
            }
        }
        return pvs;
    }
}
